package net.begincode.maiev.monitor.mail;

import net.begincode.maiev.bean.MailAlarmMessage;
import net.begincode.maiev.bean.MonitorConvertBean;
import net.begincode.maiev.handler.AlarmTaskHandler;
import net.begincode.maiev.handler.ItemHandler;
import net.begincode.maiev.handler.MonitorProjectHandler;
import net.begincode.maiev.handler.UserContext;
import net.begincode.maiev.model.AlarmRecord;
import net.begincode.maiev.model.AlarmSet;
import net.begincode.maiev.model.MonitorItem;
import net.begincode.maiev.model.MonitorProject;
import net.begincode.maiev.monitor.bean.CollectContainer;
import net.begincode.maiev.util.EmailUtils;
import net.begincode.maiev.util.ObjectUtils;
import net.begincode.maiev.util.SpringApplicationContextHolder;

import java.util.Map;

/**
 * Created by Stay on 2017/6/1  11:04.
 */
public class AlarmSetObserver implements Observer {

    private Integer id;

    private MonitorSubject monitorSubject;

    private String monitorItemName;

    private Integer timeThreshold;

    private Integer qpsThreshold;

    private Integer timeOutCount;

    private String projectName;

    private Long maxRequestTime;

    private String email;

    private Integer userId;

    private ItemHandler itemHandler = (ItemHandler) SpringApplicationContextHolder.getSpringBean("itemHandler");

    private MonitorProjectHandler monitorProjectHandler = (MonitorProjectHandler) SpringApplicationContextHolder.getSpringBean("monitorProjectHandler");

    private UserContext userContext = (UserContext) SpringApplicationContextHolder.getSpringBean("userContext");

    private AlarmTaskHandler alarmTaskHandler = (AlarmTaskHandler) SpringApplicationContextHolder.getSpringBean("alarmTaskHandler");


    public AlarmSetObserver() {
    }

    public AlarmSetObserver(AlarmSet alarmSet) {
        if (!ObjectUtils.isNull(alarmSet) && alarmSet.getMonitorItemId() != 0) {
            MonitorItem item = itemHandler.getItemById(alarmSet.getMonitorItemId());
            MonitorProject monitorProject = monitorProjectHandler.getMonitorProjectByProjectId(item.getProjectId());
            this.id = alarmSet.getId();
            this.projectName = monitorProject.getProjectName();
            this.monitorItemName = item.getMonitorItemName();
            this.timeThreshold = alarmSet.getTimeThreshold();
            this.qpsThreshold = alarmSet.getQpsThreshold();
            this.email = userContext.getUserById(alarmSet.getUserId()).getEmail();
            this.userId = alarmSet.getUserId();
            this.timeOutCount = 0;
        }
    }

    public AlarmSetObserver(MonitorSubject monitorSubject, AlarmSet alarmSet) {
        if (!ObjectUtils.isNull(alarmSet) && alarmSet.getMonitorItemId() != 0) {
            MonitorItem item = itemHandler.getItemById(alarmSet.getMonitorItemId());
            MonitorProject monitorProject = monitorProjectHandler.getMonitorProjectByProjectId(item.getProjectId());
            this.id = alarmSet.getId();
            this.projectName = monitorProject.getProjectName();
            this.monitorItemName = item.getMonitorItemName();
            this.timeThreshold = alarmSet.getTimeThreshold();
            this.qpsThreshold = alarmSet.getQpsThreshold();
            this.email = userContext.getUserById(alarmSet.getUserId()).getEmail();
            this.timeOutCount = 0;
            this.userId = alarmSet.getUserId();
            monitorSubject.addData(this);
        }
    }


    @Override
    public void alertInspect() {
        Map<String, MonitorConvertBean> dataMap = CollectContainer.getInstance().getDataMap();
        MonitorConvertBean convertBean = dataMap.get(this.monitorItemName);
        if (convertBean != null) {
            if (convertBean.getRequestMaxTime().get() > timeThreshold) {
                this.maxRequestTime = convertBean.getRequestMaxTime().get();
                timeOutCount++;
            }
            if (timeOutCount > qpsThreshold) {
                //邮件报警
                alarm();
            }
        }
    }

    private void alarm() {
        MailAlarmMessage message = new MailAlarmMessage();
        message.setMonitorName(this.monitorItemName);
        message.setProjectName(this.projectName);
        message.setMailTitle("监控告警(maiev)");
        message.setMaxTime(this.maxRequestTime);
        EmailUtils.sendEmail(this.email, message);
        AlarmRecord alarmRecord = new AlarmRecord();
        alarmRecord.setAlarmContent(this.getMonitorItemName() + "超过所设定的阈值，" + "值为" + this.getMaxRequestTime());
        alarmRecord.setUserId(this.userId);
        alarmTaskHandler.saveAlarmRecord(alarmRecord);
        this.timeOutCount = 0;
    }


    public Integer getTimeOutCount() {
        return timeOutCount;
    }

    public void setTimeOutCount(Integer timeOutCount) {
        this.timeOutCount = timeOutCount;
    }

    public MonitorSubject getMonitorSubject() {
        return monitorSubject;
    }

    public void setMonitorSubject(MonitorSubject monitorSubject) {
        this.monitorSubject = monitorSubject;
    }

    public String getMonitorItemName() {
        return monitorItemName;
    }

    public void setMonitorItemName(String monitorItemName) {
        this.monitorItemName = monitorItemName;
    }

    public Integer getTimeThreshold() {
        return timeThreshold;
    }

    public void setTimeThreshold(Integer timeThreshold) {
        this.timeThreshold = timeThreshold;
    }

    public Integer getQpsThreshold() {
        return qpsThreshold;
    }

    public void setQpsThreshold(Integer qpsThreshold) {
        this.qpsThreshold = qpsThreshold;
    }

    public String getProjectName() {
        return projectName;
    }

    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }

    public Long getMaxRequestTime() {
        return maxRequestTime;
    }

    public void setMaxRequestTime(Long maxRequestTime) {
        this.maxRequestTime = maxRequestTime;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }
}
